const fs = require('fs');
const path = require('path');
const { EventEmitter } = require('events');
const { getLogger } = require('./logger');

// 创建全局gc对象来模拟游戏引擎环境
global.gc = {
    event: new EventEmitter(),
};

class BattleLogicRunner {
    constructor(battleId = 'default') {
        this.battleSystem = null;
        this.isInitialized = false;
        this.currentRound = 0;
        this.battleId = battleId;
        this.logger = getLogger(battleId);
    }

    async initialize() {
        const startTime = Date.now();
        try {
            // 尝试编译和加载战斗逻辑
            await this.compileBattleLogic();
            await this.loadCompiledModules();
            this.isInitialized = true;
        } catch (error) {
            const duration = Date.now() - startTime;
            this.logger.warn('RUNNER', `Failed to load battle logic, using fallback (${duration}ms)`, {
                error: error.message,
                stack: error.stack,
            });
            this.isInitialized = true;
        }
    }

    async loadCompiledModules() {
        const compiledDir = path.join(__dirname, 'compiled-battle-logic');
        const startTime = Date.now();

        try {
            // 尝试加载编译后的模块
            const BattleSystemModule = require(path.join(compiledDir, 'BattleSystem.js'));
            const BattleFactoryModule = require(path.join(compiledDir, 'BattleFactory.js'));
            const BattleMapModule = require(path.join(compiledDir, 'BattleMap.js'));
            const BattlePlayerModule = require(path.join(compiledDir, 'BattlePlayer.js'));
            const CommandValidatorModule = require(path.join(compiledDir, 'CommandValidator.js'));
            const MapConstConfigsModule = require(path.join(compiledDir, 'MapConstConfigs.js'));
            const ConstModule = require(path.join(compiledDir, 'Const.js'));
            const EnumsModule = require(path.join(compiledDir, 'Enums.js'));
            const ModelModule = require(path.join(compiledDir, 'Model.js'));

            // 初始化战斗系统
            if (BattleSystemModule && BattleSystemModule.BattleSystem) {
                this.battleSystem = new BattleSystemModule.BattleSystem();

                // 为BattleSystem设置日志记录器
                if (this.battleSystem && typeof this.battleSystem.setLogger === 'function') {
                    this.battleSystem.setLogger(this.logger);
                }

                this.logger.info('RUNNER', 'BattleSystem initialized successfully');
            }
        } catch (error) {
            const duration = Date.now() - startTime;
            this.logger.error('RUNNER', `Failed to load compiled modules (${duration}ms)`, {
                error: error.message,
                stack: error.stack,
            });
            throw error;
        }
    }

    async compileBattleLogic() {
        const sourceDir = path.join(__dirname, '..', 'client', 'assets', 'battle');
        const compiledDir = path.join(__dirname, 'compiled-battle-logic');

        // 创建编译目录
        if (!fs.existsSync(compiledDir)) {
            fs.mkdirSync(compiledDir, { recursive: true });
        }

        try {
            // 使用TypeScript编译器
            const ts = require('typescript');

            // 获取所有TypeScript文件
            const tsFiles = fs.readdirSync(sourceDir).filter((file) => file.endsWith('.ts'));

            // TypeScript编译选项 - 升级到ES2022支持更好的异步功能
            const compilerOptions = {
                target: ts.ScriptTarget.ES2022,
                module: ts.ModuleKind.CommonJS,
                outDir: compiledDir,
                rootDir: sourceDir,
                strict: false,
                esModuleInterop: true,
                skipLibCheck: true,
                forceConsistentCasingInFileNames: false,
                removeComments: false,
                lib: ['ES2022', 'DOM'],
                downlevelIteration: true,
                allowSyntheticDefaultImports: true,
            };

            // 编译每个文件
            for (const file of tsFiles) {
                const sourcePath = path.join(sourceDir, file);
                const sourceCode = fs.readFileSync(sourcePath, 'utf8');

                // 编译TypeScript代码
                const result = ts.transpileModule(sourceCode, {
                    compilerOptions: compilerOptions,
                });

                // 写入编译后的JavaScript文件
                const targetPath = path.join(compiledDir, file.replace('.ts', '.js'));
                fs.writeFileSync(targetPath, result.outputText);
            }

            this.logger.info('RUNNER', 'Battle logic compiled successfully using TypeScript compiler');
        } catch (error) {
            this.logger.error('RUNNER', 'TypeScript compilation failed, using fallback logic:', error.message);
        }
    }

    async executeCommand(command) {
        const startTime = Date.now();

        try {
            // 检查是否已初始化
            if (!this.isInitialized) {
                this.logger.info('RUNNER', '战斗逻辑未初始化，开始初始化...');
                await this.initialize();
            }

            // 检查battleSystem是否存在
            if (!this.battleSystem) {
                this.logger.error('RUNNER', 'battleSystem不存在');
                return;
            }

            this.logger.info('RUNNER', '调用cmd, 执行的命令: ', command);

            // 执行命令
            const result = this.battleSystem.cmd(command);

            const duration = Date.now() - startTime;
            this.logger.info('RUNNER', '执行结果: ', result, '执行时间: ', duration, 'ms');
            return result;
        } catch (error) {
            const duration = Date.now() - startTime;
            this.logger.error('RUNNER', '执行命令失败, 错误信息: ', error.message, '执行时间: ', duration, 'ms');
            return {
                success: false,
                error: error.message,
                exception: error.stack,
            };
        }
    }

    /**
     * 初始化战斗
     * @param {Object} initCommand - 初始化命令
     * @returns {Promise<Object>} - 初始化结果
     */
    async initializeBattle(initCommand) {
        this.logger.info('RUNNER', '初始化战斗, 初始化命令: ', initCommand);

        try {
            // 确保战斗系统已初始化
            if (!this.battleSystem) {
                return { success: false, message: 'Battle system not loaded' };
            }

            // 验证initCommand格式
            if (!initCommand || initCommand.type !== 'init' || !initCommand.param) {
                return { success: false, message: 'Invalid init command format' };
            }

            // 使用cmd方法执行init命令
            if (this.battleSystem.cmd) {
                const result = this.battleSystem.cmd(initCommand);
                this.logger.info('RUNNER', '初始化战斗, 初始化结果: ', result);

                if (result.valid === true) {
                    // 获取初始化后的战斗状态，包含基地血量信息
                    const battleState = this.battleSystem.getState();

                    // 提取基地血量信息
                    let baseHealthInfo = {};
                    if (battleState && battleState.players) {
                        for (const [playerId, playerData] of Object.entries(battleState.players)) {
                            if (playerData && typeof playerData.getBaseHealth === 'function') {
                                baseHealthInfo[playerId] = {
                                    baseHealth: playerData.getBaseHealth()
                                };
                            } else if (playerData && playerData.baseHealth !== undefined) {
                                baseHealthInfo[playerId] = {
                                    baseHealth: playerData.baseHealth
                                };
                            }
                        }
                    }

                    return {
                        success: true,
                        message: 'Battle initialized successfully',
                        baseHealthInfo: baseHealthInfo
                    };
                } else {
                    this.logger.error('RUNNER', '初始化战斗, 初始化失败, 初始化结果: ', result);
                    return { success: false, message: 'Init command failed' };
                }
            } else {
                this.logger.error('RUNNER', '初始化战斗, 没有找到合适的初始化方法');
                return { success: false, message: 'No suitable initialization method available' };
            }
        } catch (error) {
            this.logger.error('RUNNER', '初始化战斗, 初始化失败, 错误信息: ', error.message);
            return { success: false, message: `Initialization error: ${error.message}` };
        }
    }

    /**
     * 执行单个玩家当前回合的命令
     * @param {string} playerId - 玩家ID
     * @param {Array} commands - 命令列表
     * @param {boolean} codeExecutionFailed - 代码执行是否失败
     * @returns {Promise<Object>} - 回合结果
     */
    async executeRound(playerId, commands, codeExecutionFailed = false) {
        this.logger.info('RUNNER', `执行玩家 ${playerId} 回合 ${this.currentRound}`, {
            codeExecutionFailed: codeExecutionFailed
        });

        try {
            // 验证战斗系统
            if (!this.battleSystem?.submitRoundCommands) {
                throw new Error('战斗系统未初始化或缺少submitRoundCommands方法');
            }

            // 验证玩家ID
            const playerIds = this.battleSystem.getPlayers();
            this.logger.info('RUNNER', `玩家ID验证 - 请求的ID: "${playerId}", 系统中的玩家列表: [${playerIds.map(id => `"${id}"`).join(', ')}]`);
            if (!playerIds || !playerIds.includes(playerId)) {
                this.logger.error('RUNNER', `玩家ID验证失败 - 请求的ID: "${playerId}" 不在系统玩家列表中: [${playerIds.map(id => `"${id}"`).join(', ')}]`);
                throw new Error(`无效的玩家ID: ${playerId}`);
            }

            // 处理命令
            const commandList = commands.filter((cmd) => !cmd.player || cmd.player === playerId);

            // 提交命令
            const result = this.battleSystem.submitRoundCommands(playerId, commandList, codeExecutionFailed);
            this.logger.info('RUNNER', `提交玩家${playerId}回合命令完成 (${commands.length}个命令)`);

            const hasError = !result.success;
            let failedCommandCount = 0;
            let details = [];

            // 从结果中提取当前玩家的数据
            if (result.result && result.result.playerCommandExecutionDetails) {
                details = result.result.playerCommandExecutionDetails || [];
                failedCommandCount = details.filter(detail => detail.isError).length;
            }

            this.logger.info('RUNNER', '提交回合命令完成', {
                playerId: playerId,
            });

            // 获取战斗状态
            const state = this.battleSystem.getState();

            // 构建结果
            const finalResult = {
                success: !hasError,
                round: state.currentRound,  // 执行完后的最新回合
                battle_ended: state.battleEnded,
                winner: state.battleResult?.winner || null,
                battleStats: state,
                failedCommandCount: failedCommandCount, // 当前玩家失败命令数
                executionDetails: details, // 当前玩家执行命令详情数组
                endCommand: result.result?.endCommand || {}, // 结束命令
                message: hasError ? (result.error || `玩家${playerId}命令执行失败`) : `玩家${playerId}回合 ${state.currentRound-1} 执行完成`,
                error: hasError ? (result.error || `玩家${playerId}命令执行失败`) : undefined,
            };

            this.logger.info('RUNNER', '玩家回合执行完成', {
                playerId: playerId,
                round: finalResult.round,
                success: finalResult.success,
                battleEnded: finalResult.battle_ended,
                winner: finalResult.winner,
                failedCommandCount: finalResult.failedCommandCount,
            });

            return finalResult;
        } catch (error) {
            this.logger.error('RUNNER', '执行回合时发生错误', {
                playerId: playerId,
                error: error.message,
                stack: error.stack,
            });

            const result = {
                success: false,
                round: this.currentRound || 0,
                battle_ended: false,
                winner: null,
                battleStats: null,
                failedCommandCount: 0,
                executionDetails: [],
                endCommand: {},
                message: `回合执行失败: ${error.message}`,
                error: error.message,
            };

            return result;
        }
    }

    getBattleState() {
        this.logger.info('RUNNER', '获取战斗状态...');

        if (!this.isInitialized || !this.battleSystem) {
            this.logger.info('RUNNER', '战斗系统未初始化');
            return {
                status: 'init',
            };
        }

        const state = this.battleSystem.getState();
        this.logger.info('RUNNER', '从 battleSystem.getState() 获取的状态', {
            currentRound: state.currentRound,
            status: state.status,
            battleEnded: state.battleEnded,
            winner: state.winner,
        });
        return state;

    }

    cleanup() {
        this.logger.info('RUNNER', '清理战斗逻辑运行器...');
        this.battleSystem = null;
        this.isInitialized = false;
    }
}

module.exports = { BattleLogicRunner };
